package com.nb.service.impl;

import com.nb.dto.patient.AppointmentDTO;
import com.nb.dto.patient.PatientInfoDTO;
import com.nb.dto.patient.ScheduleDetailDTO;
import com.nb.dto.patient.ScheduleOverviewDTO;
import com.nb.mapper.PatientMapper;
import com.nb.service.PatientService;
import com.nb.utils.CurrentHolderUtil;
import com.nb.utils.UrlUtil;
import com.nb.vo.patient.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class PatientServiceImpl implements PatientService {
    @Autowired
    private PatientMapper patientMapper;


    @Override
    public PatientInfoVO getPatientInfo() {
        PatientInfoVO patientInfoVO =patientMapper.getById(CurrentHolderUtil.getCurrentId());

        return patientInfoVO;
    }

    @Override
    public void updatePatientInfo(PatientInfoDTO patientInfoDTO) {
        // 设置当前用户ID
        patientInfoDTO.setId(CurrentHolderUtil.getCurrentId());
        // 调用Mapper执行更新
        patientMapper.updatePatientInfo(patientInfoDTO);
    }

    @Override
    public List<SourceQueryVO> getNumberSourceList() {
        // 模拟数据，实际应从数据库查询
        List<SourceQueryVO> sourceList = patientMapper.getNumberSourceList();
        return sourceList;
    }

    @Override
    public List<OrderVO> getAllOrders() {
        List<OrderVO> ordersList = patientMapper.getAllOrdersList(CurrentHolderUtil.getCurrentId());

        return ordersList;
    }

    @Override
    public void pay(String id) {

        patientMapper.updateOrderStatusById(id);
    }

    @Override
    public LatestRegistrationVO getLatestRegistration() {
        LatestRegistrationVO latestRegistrationVO= patientMapper.getLatestRegistrationByUserId(CurrentHolderUtil.getCurrentId());
        return latestRegistrationVO;
    }

    @Override
    public List<DepartmentVO> getDepartmentList() {
        List<DepartmentVO> departmentList = patientMapper.getDepartmentList();
        return departmentList;
    }

    @Override
    public DepartmentDetailVO getDepartmentDetail(String id) {
        DepartmentDetailVO departmentDetailVO = patientMapper.getDepartmentDetailByDepartmentId(id);
        return departmentDetailVO;

    }

    @Override
    public List<DepartmentDoctorVO> getDepartmentDoctor(String id) {
        List<DepartmentDoctorVO> departmentDoctorVOList = patientMapper.getDepartmentDoctorByDepartmentId(id);
        
        // 处理医生头像URL
        if (departmentDoctorVOList != null) {
            for (DepartmentDoctorVO doctor : departmentDoctorVOList) {
                if (doctor.getAwatarUrl() != null) {
                    doctor.setAwatarUrl(UrlUtil.buildFullUrl(doctor.getAwatarUrl()));
                }
            }
        }
        
        return departmentDoctorVOList;
    }


    @Override
    public List<ScheduleOverviewVO> getScheduleOverview(ScheduleOverviewDTO scheduleOverviewDTO) {
        List<ScheduleOverviewVO> scheduleOverviewVOList = patientMapper.getScheduleOverview(scheduleOverviewDTO);

        for (ScheduleOverviewVO scheduleOverviewVO : scheduleOverviewVOList) {
            // 获取日期"yyyy-MM-dd"
            String dateStr = scheduleOverviewVO.getDate();
            // 转换成星期几
            LocalDate date = LocalDate.parse(dateStr);
            String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
            int dayOfWeek = date.getDayOfWeek().getValue() % 7; // 周一是1，周日是7，转换为数组索引
            String weekDayStr = weekDays[dayOfWeek];

            // 设置星期几
            scheduleOverviewVO.setDayOfWeek(weekDayStr);
            
            // 不需要额外处理isFullyBooked，因为SQL已经返回适当的布尔值
        }

        return scheduleOverviewVOList;
    }

    @Override
    public ScheduleDetailVO getScheduleDetail(ScheduleDetailDTO scheduleDetailDTO) {
        ScheduleDetailVO scheduleDetailVO = new ScheduleDetailVO();

        // 获取时间段信息，直接获取所有时间段列表
        List<ScheduleDetailVO.TimeSlot> timeSlots = patientMapper.getAllTimeSlots(
                scheduleDetailDTO.getId(),
                scheduleDetailDTO.getDate()
        );

        scheduleDetailVO.setTimeSlots(timeSlots);

        // 获取可用医生信息
        List<ScheduleDetailVO.Doctor> doctors = patientMapper.getAvailableDoctors(
                scheduleDetailDTO.getId(),
                scheduleDetailDTO.getDate()
        );


        // 为每个医生设置可用时间段ID并处理头像URL
        for (ScheduleDetailVO.Doctor doctor : doctors) {
            String slotIds = patientMapper.getDoctorAvailableSlots(
                    doctor.getId(),
                    scheduleDetailDTO.getDate()
            );
            doctor.setAvailableSlotIds(slotIds);
            
            // 处理医生头像URL
            if (doctor.getAwatarUrl() != null) {
                doctor.setAwatarUrl(UrlUtil.buildFullUrl(doctor.getAwatarUrl()));
            }
        }

        scheduleDetailVO.setAvailableDoctors(doctors);

        return scheduleDetailVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void makeAppointment(AppointmentDTO appointmentDTO) {
        //随机生成订单编号十位数
        String orderId = String.valueOf(System.currentTimeMillis()).substring(0, 10);
        appointmentDTO.setOrderNo(orderId);

        //设置提交挂号订单时间为当前时间(yyyy-MM-dd HH:mm:ss)
        appointmentDTO.setSubmitTime(String.valueOf(LocalDateTime.now()));

        //根据线程中的用户id联表查询该用户的患者id，并将患者id设置到appointmentDTO中
        Integer userId = CurrentHolderUtil.getCurrentId();
        String patientId = patientMapper.getPatientIdByUserId(userId);
        appointmentDTO.setPatientId(patientId);

        //联表查询号源id，并将号源id设置到appointmentDTO中
        String sourceId = patientMapper.getSourceIdByDoctorIdAndTimeId(appointmentDTO);
        appointmentDTO.setSourceNo(sourceId);

        log.info("预约挂号信息:{}", appointmentDTO);

        //更新号源状态
        patientMapper.updateSourceByDoctorIdAndTimeId(appointmentDTO);

        //插入挂号订单
        patientMapper.insertRegistrationOrder(appointmentDTO);


        // 从registration_order获取订单id，医生id和患者id，插入到medical_record
        Map<String, Object> orderInfo = patientMapper.getRegistrationOrderByOrderNo(orderId);
        if (orderInfo != null) {
            Map<String, Object> medicalRecordParams = new HashMap<>();
            medicalRecordParams.put("registrationId", orderInfo.get("id"));
            medicalRecordParams.put("doctorId", orderInfo.get("doctor_id"));
            medicalRecordParams.put("patientId", orderInfo.get("patient_id"));
            medicalRecordParams.put("createTime", LocalDateTime.now());
            medicalRecordParams.put("updateTime", LocalDateTime.now());


            // 插入医疗记录
            patientMapper.insertMedicalRecord(medicalRecordParams);
            log.info("已创建医疗记录，关联挂号单号：{}", orderId);
        }

        // 从刚刚生成的medical_record记录中获取record_id，插入到examination_application中
        Integer recordId = patientMapper.getMedicalRecordIdByOrderId(orderInfo.get("id"));
        if (recordId != null) {
            // 创建基础检查申请（根据业务需求可以调整）
            Map<String, Object> examinationParams = new HashMap<>();
            examinationParams.put("recordId", recordId);
            examinationParams.put("doctorId", orderInfo.get("doctor_id"));
            examinationParams.put("createTime", LocalDateTime.now());
            examinationParams.put("updateTime", LocalDateTime.now());

            // 插入检查申请记录
            patientMapper.insertExaminationApplication(examinationParams);
            log.info("已创建检查申请，关联诊疗记录ID：{}", recordId);
        }

        //将recordId，doctorId，patientId插入到prescription表中
        if (recordId != null) {
            Map<String, Object> prescriptionParams = new HashMap<>();
            prescriptionParams.put("recordId", recordId);
            prescriptionParams.put("doctorId", orderInfo.get("doctor_id"));
            prescriptionParams.put("patientId", orderInfo.get("patient_id"));

            // 插入处方记录
            patientMapper.insertPrescription(prescriptionParams);
            log.info("已创建处方记录，关联诊疗记录ID：{}", recordId);
        }

        //将recordId 插入到medical_advice表中
        if (recordId != null) {
            Map<String, Object> medicalAdviceParams = new HashMap<>();
            medicalAdviceParams.put("recordId", recordId);
            medicalAdviceParams.put("createTime", LocalDateTime.now());
            medicalAdviceParams.put("updateTime", LocalDateTime.now());
            medicalAdviceParams.put("creatorId", orderInfo.get("doctor_id")); // 创建人ID使用医生ID

            // 插入医嘱记录
            patientMapper.insertmedicalAdvice(medicalAdviceParams);
            log.info("已创建医嘱记录，关联诊疗记录ID：{}", recordId);
        }



    }
}
